import bpy
import os
import datetime


bl_Del = {
    "name": "缩减及上色",
    "idname" : "OBJECT_PT_advanced",
    "blender": (2, 80, 0),
    "category": "Object",
    "description": "一个缩减插件",
    "author": "张鲜祥",
    "version": (1, 0, 0),
    "location": "3D视图 > 侧边栏 > 缩减上色",
}


bl_STL2DAE = {
    "name": "STL转换DAE",
    "blender": (2, 80, 0),
    "category": "Object",
    "description": "一个转换插件",
    "author": "张鲜祥",
    "version": (1, 0, 0),
    "location": "3D视图 > 侧边栏 > 转换DAE",
}


def clear_all_materials():
    # 循环访问所有材料
    for material in bpy.data.materials:
        # 使用用户的数量检查材料是否被使用
        if material.users == 0:
            # 如果没有对象使用这个材料，可以安全地删除
            bpy.data.materials.remove(material)
        else:
            # 如果材料正在使用中，首先解除所有对象的使用
            for obj in bpy.data.objects:
                # 检查对象是否有材料插槽
                if obj.type == 'MESH':
                    obj_material_slots = obj.material_slots
                    for slot in obj_material_slots:
                        if slot.material == material:
                            slot.material = None
            # 现在材料没有被任何对象使用，可以安全删除
            bpy.data.materials.remove(material)

def process_models(dir_path, output_dir,diff_color=(0.12, 0.698, 0.69, 1),ratio=0.4):
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    bpy.ops.object.select_all(action='SELECT')
    bpy.ops.object.delete()
    print("输入路径:",dir_path)
    print("输出路径:",output_dir)
    print("颜色:",diff_color)

    for file in os.listdir(dir_path):
        fmt = ''
        if file.endswith('.dae'):
            file_path = os.path.join(dir_path, file)
            bpy.ops.wm.collada_import(filepath=file_path)
            fmt = '.dae'
        elif file.endswith('.stl') or file.endswith('.STL'):
            file_path = os.path.join(dir_path, file)
            bpy.ops.wm.stl_import(filepath=file_path)
            fmt = '.stl'

        if bpy.context.selected_objects:
            obj = bpy.context.active_object
            obj.data = obj.data.copy()
            bpy.context.view_layer.objects.active = obj

            mod = obj.modifiers.new(name="Decimator", type='DECIMATE')
            mod.ratio = ratio
            bpy.ops.object.modifier_apply(modifier="Decimator")

            clear_all_materials()
            mat = bpy.data.materials.new(name="Material")
            mat.diffuse_color = diff_color
            obj.data.materials.append(mat)

            output_file_name = os.path.splitext(file)[0] + fmt
            output_path = os.path.join(output_dir, output_file_name)

            if fmt == ".dae":
                bpy.ops.wm.collada_export(filepath=output_path)
            elif fmt == ".stl":
                bpy.ops.wm.stl_export(filepath=output_path)

            bpy.ops.object.select_all(action='DESELECT')
            bpy.ops.object.select_by_type(type='MESH')
            bpy.ops.object.delete()

    print("执行完成")
    bpy.ops.object.select_all(action='SELECT')
    bpy.ops.object.delete()

class SimpleOperator(bpy.types.Operator):
    """DAE上色"""
    bl_idname = "object.my_del"  # 唯一标识符
    bl_label = "DAE上色"           # 按钮上的文本

    def execute(self, context):
        # 访问滑动条值、文件路径和颜色
        slider_value = context.scene.my_slider_value
        file_path = context.scene.my_file_path
        color = context.scene.my_color

        file_path = context.scene.my_file_path
        out_path = file_path + "2"
        context.scene.my_export_dir = out_path
        process_models(file_path, out_path ,color,slider_value) 
        timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        context.scene.my_execution_status = f"执行完成：{timestamp}"
        return {'FINISHED'}
    
class STL2DAE(bpy.types.Operator):
    """STL转换"""
    bl_idname = "object.my_stl2dae"  # 唯一标识符
    bl_label = "STL转DAE"           # 按钮上的文本
    def execute(self, context):
        # 访问滑动条值、文件路径和颜色
        file_path = context.scene.my_file_path
        stl2DaeModel(file_path,file_path)
        timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        context.scene.my_execution_status = f"执行完成：{timestamp}"
        return {'FINISHED'}
    

class SimplePanel(bpy.types.Panel):
    """在对象属性窗口中创建一个面板"""
    bl_label = "缩减上色"  # 面板标题
    bl_idname = "OBJECT_PT_my_panel"  # 唯一标识符
    bl_space_type = 'VIEW_3D'  # 在 3D 视图中显示
    bl_region_type = 'UI'  # 在侧边栏显示
    bl_category = '自定义插件'  # 面板的标签
    def draw(self, context):
        layout = self.layout
        scene = context.scene

        # 文件路径选择器
        row = layout.row()
        row.prop(scene, "my_file_path", text="文件路径")

        # 滑动条
        row = layout.row()
        row.prop(scene, "my_slider_value", text="缩放比例")

        # 颜色选择器
        row = layout.row()
        row.prop(scene, "my_color", text="选择颜色")

        # 执行按钮
        row = layout.row()
        row.operator(SimpleOperator.bl_idname, text="执行缩减")

        row = layout.row()
        row.operator(STL2DAE.bl_idname, text="执行转换")

        # 标签
        row = layout.row()
        row.label(text=scene.my_export_dir)

        # 标签
        row = layout.row()
        row.label(text=scene.my_execution_status)

def register():
    bpy.utils.register_class(SimpleOperator)
    bpy.utils.register_class(STL2DAE)    
    bpy.utils.register_class(SimplePanel)
    bpy.types.Scene.my_slider_value = bpy.props.FloatProperty(
        name="缩放比例",
        description="从0到1的滑动条",
        default=0.5,
        min=0.0,
        max=1.0
    )
    bpy.types.Scene.my_file_path = bpy.props.StringProperty(
        name="文件路径",
        description="选择一个目录",
        default="",
        subtype='DIR_PATH'
    )
    bpy.types.Scene.my_color = bpy.props.FloatVectorProperty(
        name="颜色",
        description="选择一个颜色",
        default=(1.0, 1.0, 1.0,1.0),
        subtype='COLOR_GAMMA',
        size=4,
        min=0.0,
        max=1.0
    )
    bpy.types.Scene.my_export_dir = bpy.props.StringProperty(
        name="输出目录",
        description="展示输出路径",
        default="空"
    )
    bpy.types.Scene.my_execution_status = bpy.props.StringProperty(
        name="执行状态",
        description="显示最后一次执行的状态和时间",
        default="未执行"
    )

def unregister():
    bpy.utils.unregister_class(SimplePanel)
    bpy.utils.unregister_class(STL2DAE)
    bpy.utils.unregister_class(SimpleOperator)
    del bpy.types.Scene.my_slider_value
    del bpy.types.Scene.my_file_path
    del bpy.types.Scene.my_color

if __name__ == "__main__":
    register()


def stl2DaeModel(source_folder, output_folder):
    bpy.ops.object.select_all(action='SELECT')
    bpy.ops.object.delete()

    for file_name in os.listdir(source_folder):
        if file_name.endswith('.stl') or file_name.endswith('.STL'):
            bpy.ops.object.select_all(action='SELECT')
            bpy.ops.object.delete()
            file_path = os.path.join(source_folder, file_name)
            
            bpy.ops.import_mesh.stl(filepath=file_path, global_scale=1, use_scene_unit=True, axis_forward='Y', axis_up='Z')
            
            bpy.ops.object.select_all(action='SELECT')
            obj = bpy.context.selected_objects[0]

            mat = bpy.data.materials.new(name="MetalGreen")
            mat.use_nodes = True
            nodes = mat.node_tree.nodes
            bsdf = nodes["原理化BSDF"]
            if not bsdf:
                bsdf = nodes.new(type='ShaderNodeBsdfPrincipled')
            bsdf.inputs[0].default_value = (0.0, 1.0, 0.0, 1)
            bsdf.inputs[1].default_value = 1.0
            bsdf.inputs[2].default_value = 0.5
            
            if obj.data.materials:
                obj.data.materials[0] = mat
            else:
                obj.data.materials.append(mat)

            output_file_name = os.path.splitext(file_name)[0] + '.dae'
            output_path = os.path.join(output_folder, output_file_name)
            bpy.ops.wm.collada_export(filepath=output_path,selected=True, include_children=True,export_global_forward_selection='Z',export_global_up_selection='-Y')


    bpy.ops.object.select_all(action='SELECT')
    bpy.ops.object.delete()